
#ifndef _TYPE_LIST_H_
#define _TYPE_LIST_H_

struct null_type{};

template<class T, class U>
struct type_list
{
	typedef T head;
	typedef U tail;
};

// generate typelist
template<class T1 = null_type, class T2 = null_type, class T3 = null_type,
         class T4 = null_type, class T5 = null_type, class T6 = null_type,
		 class T7 = null_type, class T8 = null_type>
struct make_type_list
{
	private:
		typedef typename make_type_list<T2,T3,T4,T5,T6,T7,T8>::result tail_result;
	public:
		typedef type_list<T1,tail_result> result;
};

template<>
struct make_type_list<>
{
	public:
		typedef null_type result;
};

// length of type list

template<class T>
struct length;

template<class T, class U>
struct length<type_list<T,U> >
{
	enum {value = 1 + length<U>::value};
};

template<>
struct length<null_type>
{
	enum {value = 0};
};


template<class T, unsigned int i>
struct at;

template<class Head, class Tail>
struct at<type_list<Head,Tail>,0>
{
	typedef Head result;
};

template<class Head, class Tail, unsigned int i>
struct at<type_list<Head,Tail>,i>
{
	typedef typename at<Tail,i-1>::result result;
};

/*
int main()
{
	make_type_list<int,long,char> s;
	int ret = length<make_type_list<int,long,char>::result>::value;
	printf("%d\n",ret);

	at<make_type_list<int,long,char>::result,0>::result v;
	v = 999;
	printf("%d\n",v);
	return 0;
}
*/

#endif 
